package cn.dzh.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import io.jsonwebtoken.*;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import static cn.dzh.constant.JwtClaimsConstant.SECRETKEY;
import static cn.dzh.constant.JwtClaimsConstant.TTLMILLIS;


public class JwtUtil {
    /**
     * 生成jwt
     * 使用Hs256算法, 私匙使用固定秘钥
     * @param claims    设置的信息
     * @return Token
     */
    public static String createJWT(Map<String, String> claims) {
        // 通过Jwts对象的Builder方法创建一个JwtBuilder对象
        JwtBuilder jwtBuilder=Jwts.builder();
        String jwtToken = jwtBuilder
                //设置头信息，typ是头类型，alg是编码算法
                //Header
                .setHeaderParam("typ","JWT")
                .setHeaderParam("alg","HS256")
                //payload,载荷，也就是存数据的部分
                .claim("res",claims)
                //加一个主题，也就是前端获取到的数据名称
                .setSubject("Token")
                //设置有效期 7天
                .setExpiration(new Date(System.currentTimeMillis()+TTLMILLIS))
                .setId(UUID.randomUUID().toString())
                //Signature 设置标签（签名）识别的方式，解密算法和salt
                .signWith(SignatureAlgorithm.HS256,SECRETKEY.getBytes())
                //拼接Header、payload和Signature成一个完整的Token
                .compact();
        return jwtToken;
    }

    /**
     * Token解密
     * @param token     加密后的token
     * @return claims   得到载荷
     */
    public static Claims parseJWT(String token) {
        // 得到DefaultJwtParser
        Claims claims = Jwts.parser()
                // 设置签名的秘钥
                .setSigningKey(SECRETKEY.getBytes(StandardCharsets.UTF_8))
                // 设置需要解析的jwt
                .parseClaimsJws(token).getBody();
        return claims;
    }




    /**
     * 查看Token是否过期
     * @param token
     * @return false 未过期，true 已过期
     */
    public static Boolean tokenExpired(String token) {
        try {
            Claims claims = Jwts.parser().setSigningKey(SECRETKEY.getBytes()).parseClaimsJws(token).getBody();
            Date expiration = claims.getExpiration();
            Date currentDate = new Date();
            return expiration.before(currentDate);
        } catch (ExpiredJwtException ex) {
            return true;
        } catch (Exception ex) {
            return true;
        }
    }



    /**
     * 根据Token获得UserID 可以进行权限验证
     * @param token
     * @return UserID
     */
    public static String parseJWTGetUserID(String token) {
        Claims claims = parseJWT(token);
        Object res = claims.get("res");
        if (res instanceof Map) {
            Map<String, Object> resMap = (Map<String, Object>) res;
            Object userID = resMap.get("userId");
            if (userID != null && userID instanceof String) {
                return (String) userID;
            }
        }
        return null;
    }
    /**
     * 根据Token获得RoleID 可以进行权限验证
     * @param token
     * @return UserID
     */
    public static String parseJWTGetRoleID(String token) {
        Claims claims = parseJWT(token);
        Object res = claims.get("res");
        if (res instanceof Map) {
            Map<String, Object> resMap = (Map<String, Object>) res;
            Object userID = resMap.get("roleId");
            if (userID != null && userID instanceof String) {
                return (String) userID;
            }
        }
        return null;
    }

    /**
     * 根据Token获得RoleID 可以进行权限验证
     * @param token
     * @return UserID
     */
    public static String parseJWTGetUserName(String token) {
        Claims claims = parseJWT(token);
        Object res = claims.get("res");
        if (res instanceof Map) {
            Map<String, Object> resMap = (Map<String, Object>) res;
            Object userID = resMap.get("username");
            if (userID != null && userID instanceof String) {
                return (String) userID;
            }
        }
        return null;
    }

    /**
     * 根据Token获得RoleID 可以进行权限验证
     * @param token
     * @return UserID
     */
    public static String parseJWTGetRoleName(String token) {
        Claims claims = parseJWT(token);
        Object res = claims.get("res");
        if (res instanceof Map) {
            Map<String, Object> resMap = (Map<String, Object>) res;
            Object userID = resMap.get("rolename");
            if (userID != null && userID instanceof String) {
                return (String) userID;
            }
        }
        return null;
    }
    public static String parseJWTGetRoleCode(String token) {
        Claims claims = parseJWT(token);
        Object res = claims.get("res");
        if (res instanceof Map) {
            Map<String, Object> resMap = (Map<String, Object>) res;
            Object userID = resMap.get("rolecode");
            if (userID != null && userID instanceof String) {
                return (String) userID;
            }
        }
        return null;
    }

}
